package pl.enigmatic.logging;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.sql.Date;
import java.sql.Time;

import pl.enigmatic.util.Strings;


public class Logger {

	private Logger() {}

	private static String file = "log.log";
	private static final PrintStream out = System.out;
	private static final PrintStream err = System.err;
	private static boolean log = true;

	public static void log(final Object obj) {
		if (log) {
			try {
				final BufferedWriter writer = new BufferedWriter(new FileWriter(System.getProperty("user.dir") + "\\" + file, true));
				writer.write("[" + new Date(System.currentTimeMillis()) + " " + new Time(System.currentTimeMillis()));
				writer.write("]: ");
				writer.write(obj.toString());
				writer.write("\nat:\n");
				final StackTraceElement elt[] = new Exception().getStackTrace();
				for (int i = 1; i < elt.length;) {
					writer.write("\t" + elt[i++].toString() + "\n");
				}
				writer.write("\n");
				writer.close();
			} catch (final IOException e) {}
			System.out.println(Strings.toString(obj));
		}
	}

	public static String getQualifiedMethodName(final int depth) {
		final Exception e = new Exception();
		if (depth >= e.getStackTrace().length) { return null; }
		final StackTraceElement trace = e.getStackTrace()[depth];
		return trace.getClassName() + "." + trace.getMethodName();
	}

	public static String getQualifiedMethodName() {
		String method = Logger.class.getName();
		for (int depth = 0; method != null && method.startsWith(Logger.class.getName()); depth++) {
			method = getQualifiedMethodName(depth);
		}
		return method;
	}

	public static String getMethodName(final int depth) {
		final String[] split = getQualifiedMethodName(depth + 1).split("\\.");
		return split[split.length - 1];
	}

	public static String getMethodName() {
		final String[] split = getQualifiedMethodName().split("\\.");
		return split[split.length - 1];
	}

	public static String get(final String info) {
		return getMethodName() + ": " + info;
	}

	public static void print(final String info) {
		out.print(get(info));
	}

	public static void println(final String info) {
		out.println(get(info));
	}

	public static void err(final String info) {
		err.print(get(info));
	}

	public static void errln(final String info) {
		err.println(get(info));
	}

	public static void print(final Object obj) {
		print(Strings.toString(obj));
	}

	public static void println(final Object obj) {
		println(Strings.toString(obj));
	}

	public static void err(final Object obj) {
		err(Strings.toString(obj));
	}

	public static void errln(final Object obj) {
		errln(Strings.toString(obj));
	}

	public static void in(final Object o) {
		println("IN: " + Strings.toString(o));
	}

	public static void in() {
		in("");
	}

	public static void out(final Object o) {
		println("OUT: " + Strings.toString(o));
	}

	public static void out() {
		out("");
	}

	public static void stack() {
		new Exception().printStackTrace();
	}

	public static void formatln(final String format, final Object... args) {
		println(String.format(format, args));
	}

}
